﻿using System;
using System.Collections.Generic;
using System.Linq;
using GigaSite.Domain.Entities;
using GigaSite.Domain.Enums;
using GigaSite.Domain.Interfaces.Repositories;

namespace GigaSite.Domain.DAL.Repositories
{
    /// <summary>
    /// СУБД реализация репозитория компаний
    /// </summary>
    public class CompaniesRepository: BaseRepository<Company>, ICompaniesRepository
    {
        /// <summary>
        /// Базовый конструктор
        /// </summary>
        /// <param name="dataContext"></param>
        public CompaniesRepository(GigaDataContext dataContext) : base(dataContext)
        {
        }

        /// <summary>
        /// Загружает указанную сущность по ее идентификатору
        /// </summary>
        /// <param name="id">Идентификатор сущности</param>
        /// <returns>Сущность с указанным идентификатором или Null</returns>
        public override Company Load(long id)
        {
            return Find(c => c.Id == id);
        }

        /// <summary>
        /// Добавляет посетителя к компании под указанной ролью
        /// </summary>
        /// <param name="company">Компания</param>
        /// <param name="visitor">Посетитель</param>
        /// <param name="role">Роль, по умолчанию просто посетитель</param>
        public void AddVisitor(Company company, User visitor, VisitorTypes role = VisitorTypes.Visitor)
        {
            // Ищем, является ли уже посетитель у компании
            var mapping = company.CompanyVisitors.FirstOrDefault(v => v.UserId == visitor.Id);

            // Если нет то добавляем
            if (mapping == null)
            {
                mapping =  new CompanyVisitor()
                               {
                                   Accepted = true,
                                   Company = company,
                                   User = visitor,
                                   Role = role,
                                   DateCreated = DateTime.Now
                               };
                DataContext.CompanyVisitors.InsertOnSubmit(mapping);
                company.CompanyVisitors.Add(mapping);
            }
        }

        /// <summary>
        /// Удаляет посетителя у компании
        /// </summary>
        /// <param name="company">Компания</param>
        /// <param name="visitor">Посетитель компании</param>
        public void RemoveVisitor(Company company, User visitor)
        {
            // Ищем, является ли уже посетитель у компании
            var mapping = company.CompanyVisitors.FirstOrDefault(v => v.UserId == visitor.Id);

            // Если да то удаляем
            if (mapping != null)
            {
                DataContext.CompanyVisitors.DeleteOnSubmit(mapping);
                company.CompanyVisitors.Remove(mapping);
            }
        }

        /// <summary>
        /// Создает новую компанию в системе для указанного пользователя и устанавливает ее в указанных категориях
        /// </summary>
        /// <param name="company">Компания</param>
        /// <param name="owner">Пользователь зарегистрировавший компанию</param>
        /// <param name="categories">Категории к которым компания принадлежит</param>
        public void CreateCompany(Company company, User owner, IEnumerable<Category> categories)
        {
            // Создаем компанию и устанавливаем создавшего пользователя как первого посетителя и владельца
            Add(company);
            AddVisitor(company,owner,VisitorTypes.Owner);

            // Добавляем компанию в указанные категории
            DataContext.CompanyToCategoryMappings.InsertAllOnSubmit(categories.Select(c => new CompanyToCategoryMapping()
                                                                                               {
                                                                                                   Category = c,
                                                                                                   Company = company,
                                                                                                   DateCreated = DateTime.Now
                                                                                               }));
        }

        /// <summary>
        /// Получает название компании по системному имени
        /// </summary>
        /// <param name="systemName">системное имя компании</param>
        /// <returns>Объект компании или null если его не найдено</returns>
        public Company GetCompanyBySystemName(string systemName)
        {
            return Find(c => c.SystemName == systemName);
        }
    }
}